
<!-- 该示例使用 vue 进行计算 | 当然其他框架或原生JS算法同理(只不过获取数据的方式不同而已) -->
<!-- 注意: 切勿在元素未渲染之前进行获取(否则会报错) -->
<!-- error: Invalid array length --> 
<!-- https://blog.csdn.net/weixin_44198965/article/details/117082731?spm=1001.2014.3001.5501 -->


<!-- 你可以随意更改item宽度及数量等等 | 屏幕改变会自动进行计算 -->
<!-- 注意: 请不要给item子元素设置右边距(margin-right) 这会影响计算(除非你总宽度-右边距) 然后再正常计算 -->

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <script src="https://cdn.bootcdn.net/ajax/libs/vue/2.6.12/vue.js"></script>
    <title>Vue - 完整示例</title>
    <style>
        *{
            padding: 0;
            margin: 0;
        }
        
        /* 父元素 */
        .content{
            display: flex;
            justify-content: space-around;
            flex-direction: row;
	        flex-wrap: wrap;
        }
        /* END */

        /* 子元素 */
        .item{
            background: rgb(207, 205, 209);
            width: 400px;
            height: 400px;
            margin-bottom: 50px;/* item下距离 */

            /* 文字居中一下 */
            text-align: center;
            line-height: 400px;
            /* END */
        }
        /* END */

    </style>
</head>
<body>
    <section id="app">
        <div class="content">

            <!-- 正常列表 -->
            <div
            v-for="(item, index) in list"
            :key="index"
            class="item">
                {{ item.name }} - {{ item.age }}
            </div>
            <!-- END -->


            <!-- 补元素(Knock on the blackboard) -->
            <!-- class指定为item(即正常子元素的class) -->
            <!-- 并且设置为透明不可见(或高度为0) -->
            <div
            v-for="item in repairDOM"
            class="item"
            style="opacity: 0;"
            >
                你可以降低透明度(opacity)来看补在了哪里
            </div>
            <!-- END -->

        </div>
    </section>
<script>
var vm = new Vue({

    el: '#app',
    data(){
        return {
            
            // 列表数据
            list: [
                { name: '小李', age: '15'},
                { name: '小红', age: '18'},
                { name: '小王', age: '85'},
                { name: '小张', age: '35'},
                { name: '小孙', age: '55'},
                { name: '小刘', age: '99'},
            ],

            // 补元素(Number类型 | 需要补的数量)
            repairDOM: 0

        }
    },


    mounted(){

        // 重置布局
        this.resetLayout()
    },

    // 如页面有数据更新请用它
    // 这个钩子函数非常有用(有懒加载极为重要)
    updated(){

        // 触发它即可
        //this.resetLayout()
    },

    methods: {

        /*
         * 重置布局
         * 最后一行元素不满一行的时候左对齐(补全item)
         * return void
         */
         resetLayout: function()
         {

            // 1. 获取屏幕总宽度(即浏览器窗口的宽度)
            var allWidth = document.body.clientWidth

            // 2. 获取共有多少个item项(即list列表一个多少个元素)
            var allItem = this.list.length

            // 3. 获取单个item项宽度(即单个item元素的宽度是多少)
            var dom = document.querySelector('.item').scrollWidth

            // 4. [结果取整] 计算一行能放多少个item项(即一排能放多少个元素)
            // 公式: [屏幕总宽度] / [单个item项宽度]
            var line = parseInt(allWidth / dom)

            // 5. 计算需要补多少个item项(元素不需要补的时候(=0)必须作处理)
            // 公式: ( [总item项数量] % [一行能放多少个item项] ) 
            // 如果等于0则证明不需要补 | 反之一行减去补全
            var result = (allItem % line) == 0 ? 0 : line - (allItem % line)

            // 6. 通知视图进行补元素(渲染视图上的隐藏元素)
            this.repairDOM = result

            // alert
            window.alert(`该屏幕尺寸需要补:  ${result} 个元素~`)
         }
    }
})
</script>
</body>
</html>